import { ChatGPTAPI } from 'chatgpt'
import { WechatyBuilder } from 'wechaty'
import qrcodeTerminal from 'qrcode-terminal'
import configMessage from './config.js'
const { sessionToken, keyWordArr, qrCodeImageUrl } = configMessage

const conversationPool = new Map() // 会话池
const api = new ChatGPTAPI({
  sessionToken: sessionToken,
  markdown: false
})
await api.ensureAuth()

const wechaty = WechatyBuilder.build({
  name: 'sun-bot',
  puppet: 'wechaty-puppet-wechat',
  puppetOptions: {
    uos: true
  }
})

wechaty
  .on('scan', (qrcode, status) => {
    qrcodeTerminal.generate(qrcode) // 在console端显示二维码
    // 这个是生成二维码的链接，可以在不安装qrcode-terminal的情况下显示二维码
    // console.log(qrCodeImageUrl(qrcode))
  })
  .on('login', user => console.log(`${user}: 登录成功`))
  .on('logout', user => console.log(`${user}: 登出成功`))
  .on('message', async message => {
    const contact = message.talker() // 发消息人
    const receiver = message.listener() // 收消息人，当前微信号
    let content = message.text() // 消息内容
    const room = message.room() // 是否是群消息
    if (!wechaty.Message.Type.Text) {
      // 不是文本消息
      return
    }
    if (room) {
      // 在群里
      const topic = await room.topic()
      if (await message.mentionSelf() || content.includes(`@${receiver?.name()}`) || content.includes(`/c${receiver?.name()}`)) {
        // 被@或者@了别人
        let receiverName = ''
        if (receiver) {
          const alias = await room.alias(receiver)
          receiverName = alias || receiver.name()
        }
        const groupContent = content.replace(`@${receiverName}`, '')
        console.log(`groupContent:${groupContent}`)
        if (groupContent) {
          content = groupContent.trim()
          if (!content.startsWith('/c')) {
            // 在群里@的话就回复
            await chatgptReply(room, contact, content)
          }
        } else {
          //只@没有内容
          console.log(`@事件. 群名称: ${topic} 发送人: ${contact} 消息内容: ${content}`)
        }
      }
      // console.log(`群名称: ${topic} 发送人: ${contact} 消息内容: ${content}`)
      // reply(room, contact, content)
    } else {
      console.log(`发送人: ${contact} 消息内容: ${content}`)
      reply(null, contact, content)
    }
  })
  .start()

async function send(contact, message) {
  try {
    await contact.say(message)
  } catch (e) {
    console.error(e)
  }
}

async function getConversion(contact) {
  // 维持回话池
  let conversation = conversationPool.get(contact.id)
  if (!conversation) {
    conversation = api.getConversation()
    conversationPool.set(contact.id, conversation)
  }
  return conversation
}

async function chatgptReply(room, contact, request) {
  // chatGPT回复
  console.log(`contact: ${contact} request: ${request}`)
  let response = '出了一点小问题，请稍后重试下...'
  try {
    const conversation = await getConversion(contact)
    response = await conversation.sendMessage(request, {
      timeoutMs: 2 * 60 * 1000
    })
    // response = await api.sendMessage(request, {
    //   timeoutMs: 2 * 60 * 1000
    // })
    console.log(`contact: ${contact} response: ${response}`)
  } catch (e) {
    if (e.message === 'ChatGPTAPI error 429') {
      response = '请稍等一下哦，我还在思考你的上一个问题'
    }
    console.error(e)
    // 尝试刷新token
    if (await !api.getIsAuthenticated()) {
      // 刷新失败，需要重新登录
      console.error('Unauthenticated')
      response = 'ChatGPT的session过期, 请重新输入'
    }
  }
  response = `${request} \n ------------------------ \n` + response
  const target = room || contact
  await send(target, response)
}

async function reply(room, contact, content) {
  // 微信回复
  content = content.trim()
  // if (content.startsWith('chatgpt ')) {
  //   const request = content.replace('chatgpt ', '')
  //   await chatgptReply(room, contact, request)
  // }
  keywordHandler(keyWordArr, room, contact, content)
}

function keywordHandler(arr, room, contact, content) {
  // 添加群里的关键词回复
  arr.forEach(async item => {
    if (content.startsWith(item) || content.startsWith(`${item} `) || content.startsWith(`${item},`) || content.startsWith(`${item}，`)) {
      const request = content.replace(`${item}`, '').replace(`${item} `, '').replace(`${item},`, '').replace(`${item}，`, '')
      await chatgptReply(room, contact, request)
    }
  })
}